package com.hjx.movie.core.system.advices;

import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.hjx.movie.common.utils.Result;
import com.hjx.movie.common.utils.ResultType;
import com.hjx.movie.common.utils.exceptions.CustomException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.validation.BindException;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.util.List;
import java.util.stream.Collectors;


/**
 * <p>Title:</p>
 * <p>Description:</p>
 *
 * @author hjx
 * @date 2020/6/11 - 15:29
 */
@Slf4j
@RestControllerAdvice
public class ExceptionAdvice {
    @ExceptionHandler({CustomException.class})
    public Result customException(CustomException e){
        log.error("ExceptionAdvice Throw CustomException:{}",e.getMessage());
        e.printStackTrace();
        return Result.error(e);
    }

    @ExceptionHandler({IllegalArgumentException.class,IllegalStateException.class})
    public Result handleIllegalException(IllegalArgumentException e){
        log.error("ExceptionAdvice Throw IllegalException:{}",e.getMessage());
        return Result.error(ResultType.USER_INPUT_ERROR,e.getMessage());
    }

    @ExceptionHandler({JWTVerificationException.class, JWTDecodeException.class})
    public Result error(Exception e){
        log.error("ExceptionAdvice Throw Exception:{}",e.getMessage());
        return Result.error(ResultType.TOKEN_ERROR,e.getMessage());
    }


    @ExceptionHandler(Exception.class)
    public Result UnknownException(Exception e){
        e.printStackTrace();
        return Result.error(ResultType.SYSTEM_ERROR);
    }

    @ExceptionHandler(BindException.class)
    public Result validationErrorHandler(BindException ex) {
        // 同样是获取BindingResult对象，然后获取其中的错误信息
        // 如果前面开启了fail_fast，事实上这里只会有一个信息
        //如果没有，则可能又多个
        List<String> errorInformation = ex.getBindingResult().getAllErrors()
                .stream()
                .map(ObjectError::getDefaultMessage)
                .collect(Collectors.toList());
        return Result.error(ResultType.USER_INPUT_ERROR,errorInformation.get(0));
    }
}
